import crypto from "crypto";

export class Token {
  private static SECRET = "time-logger";

  static createToken<T extends Record<string, any>>(
    obj: T,
    // timeout: number = 24 * 60 * 1000
    timeout: number = 30 * 1000
  ) {
    const obj2 = {
      data: obj, //payload
      created: parseInt(`${Date.now() / 1000}`), //token生成的时间的，单位秒
      exp: timeout, //token有效期
    };
    //payload信息
    const base64Str = Buffer.from(JSON.stringify(obj2), "utf8").toString(
      "base64"
    );
    //添加签名，防篡改
    const hash = crypto.createHmac("sha256", this.SECRET);
    hash.update(base64Str);
    const signature = hash.digest("base64");
    return base64Str + "." + signature;
  }

  static decodeToken<T extends Record<string, any>>(token?: string) {
    if (!token) return false;
    const decArr = token.split(".");
    if (decArr.length < 2) {
      // token不合法
      return false;
    }
    let payload: Record<string, any> = {};
    //将payload json字符串 解析为对象
    try {
      payload = JSON.parse(Buffer.from(decArr[0], "base64").toString("utf8"));
    } catch (e) {
      return false;
    }
    //检验签名
    const hash = crypto.createHmac("sha256", this.SECRET);
    hash.update(decArr[0]);
    const checkSignature = hash.digest("base64");
    return {
      payload: payload as {
        data: T;
        created: number;
        exp: number;
      },
      signature: decArr[1],
      checkSignature: checkSignature,
    };
  }

  static checkToken(token?: string) {
    let resDecode = this.decodeToken(token);
    if (!resDecode) {
      return false;
    }
    //是否过期
    let expState =
      parseInt(`${Date.now() / 1000}`) - resDecode.payload.created >
      resDecode.payload.exp
        ? false
        : true;
    if (resDecode.signature === resDecode.checkSignature && expState) {
      return true;
    }
    return false;
  }
}
